package com.guigu.guligateway.config;

import com.guigu.gulicommon.constant.enumes.res.ServerResCode;
import com.guigu.gulicommon.entity.pojo.res.Res;
import lombok.extern.log4j.Log4j2;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * gateway异常处理
 * <p>
 * 由于gateway的异常处理优先级高于全局异常处理，所以需要自定义一个过滤器，将异常处理优先级调高
 * @author 陈俊杰
 */
@Log4j2
@Component
public class GatewayGlobalErrorFilterConfig implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        return chain.filter(exchange).onErrorResume(error -> {

            ServerHttpResponse response = exchange.getResponse();
            // 设置 HTTP 状态码
            response.setStatusCode(HttpStatus.OK);

            // 创建错误响应对象
            Res<Object> res = new Res<>(ServerResCode.SERVICE_UNAVAILABLE);
            // 设置响应体
            response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_VALUE);

            // 返回错误响应
            return response.writeWith(Mono.just(response.bufferFactory().wrap(res.toJson().getBytes())));
        });
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE; // 设置优先级
    }

}
